// ShapeDoc.cpp : implementation file
//

#include "stdafx.h"
#include "U7FileTool.h"
#include "ShapeDoc.h"

#include "U7FileDefs.h"

// CShapeDoc

IMPLEMENT_DYNCREATE(CShapeDoc, CDocument)

CShapeDoc::CShapeDoc()
{
	m_pShapeFile = NULL;
}

BOOL CShapeDoc::OnNewDocument()
{
	if (!CDocument::OnNewDocument())
		return FALSE;
	return TRUE;
}

CShapeDoc::~CShapeDoc()
{
	if ( m_pShapeFile )
		delete [] m_pShapeFile;
}

int CShapeDoc::GetShapeCount() const
{
	if ( m_pShapeFile )
		return ((PFLEXFILEHEADER)m_pShapeFile)->count;

	return 0;
}

PSHAPEENTRY CShapeDoc::GetShapeFile(UINT index, long& length) const
{
	PFLEXFILEHEADER pHeader = (PFLEXFILEHEADER)m_pShapeFile;
	if ( pHeader && (UINT)pHeader->count > index )
	{
		PFLEXFILEENTRY pEntry = (PFLEXFILEENTRY)(pHeader+1) + index;
		PSHAPEENTRY pShapeEntry = (PSHAPEENTRY)(m_pShapeFile + pEntry->offset);
		length = pEntry->size;

		return pShapeEntry;
	}

	return NULL;
}

BEGIN_MESSAGE_MAP(CShapeDoc, CDocument)
END_MESSAGE_MAP()


// CShapeDoc diagnostics

#ifdef _DEBUG
void CShapeDoc::AssertValid() const
{
	CDocument::AssertValid();
}

#ifndef _WIN32_WCE
void CShapeDoc::Dump(CDumpContext& dc) const
{
	CDocument::Dump(dc);
}
#endif
#endif //_DEBUG

#ifndef _WIN32_WCE
// CShapeDoc serialization

void CShapeDoc::Serialize(CArchive& ar)
{
	if (ar.IsStoring())
	{
		// TODO: add storing code here
	}
	else
	{
		// TODO: add loading code here
		CFile* pFile = ar.GetFile();

		UINT uiFileLength = (UINT)pFile->GetLength();
		m_pShapeFile = new BYTE[uiFileLength];
		if ( !m_pShapeFile )
			AfxThrowMemoryException();

		if ( pFile->Read( m_pShapeFile, uiFileLength ) != uiFileLength )
			AfxThrowFileException(CFileException::genericException,100);

		// sanity check!!!
		PFLEXFILEHEADER pHeader = (PFLEXFILEHEADER)m_pShapeFile;
		PFLEXFILEENTRY pEntry = (PFLEXFILEENTRY)(pHeader+1);
		PFLEXFILEENTRY pLastEntry = NULL;
		UINT uiBytes = 0;

		CString title = pFile->GetFileTitle();
		if ( title == _T("SHAPES.VGA") ) // only for shapes.vga
		for ( long e = 0; e < pHeader->count; e++ )
		{
			if ( (UINT)pEntry->offset >= uiFileLength || uiBytes >= uiFileLength )
				AfxThrowFileException(CFileException::genericException,101);

			if ( e <= 0x95 ) // game tile
			{
				ASSERT(pEntry->size % sizeof(TILE) == 0);
				//TRACE("%3d:%08X) %d tiles\n", e, (char*)pEntry - (char*)pHeader, pEntry->size/sizeof(TILE));
			}
			else if ( e <= 0x3FF ) // game shapes
			{
				PSHAPEENTRY pShapeEntry = (PSHAPEENTRY)(m_pShapeFile + pEntry->offset);
				ASSERT( pShapeEntry->size == pEntry->size );

				int nFrameCount = pShapeEntry->offset[0] / sizeof(long) - 1;
				//TRACE("%3d:%08X) %d frames\n", e, (char*)pEntry - (char*)pHeader, nFrameCount);

				for ( int n = 0; n < nFrameCount; n++ )
				{
					PFRAMEENTRY pFrameEntry = (PFRAMEENTRY)((char*)pShapeEntry + pShapeEntry->offset[n]);
					/*TRACE("\t rx%3d,lx%3d,ly%3d,ry%3d\n",
						pFrameEntry->rightX,
						pFrameEntry->leftX,
						pFrameEntry->topY,
						pFrameEntry->bottomY);*/
				}
			}

			if ( pLastEntry != NULL && pLastEntry->offset + pLastEntry->size != pEntry->offset )
			{
				TRACE("%3d) offset:%d, size:%d\n", e, pEntry->offset, pEntry->size);
			}

			uiBytes += pEntry->size;
			pLastEntry = pEntry;
			pEntry++;
		}

		if ( title == _T("SHAPES.VGA") )
			theApp.m_pShapeFile = m_pShapeFile;
	}
}
#endif


// CShapeDoc commands


void CShapeDoc::DeleteContents()
{
	// TODO: Add your specialized code here and/or call the base class
	if ( m_pShapeFile )
	{
		delete [] m_pShapeFile;
		m_pShapeFile = NULL;
	}

	CDocument::DeleteContents();
}
